package cn.cdutetc.library.common;

import cn.cdutetc.library.entity.dto.BookImportDTO;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;

/**
 * 图书Excel数据监听器
 */
@Slf4j
public class BookExcelAnalysisEventListener implements ReadListener<BookImportDTO> {

    /**
     * 每隔5条存储数据库，实际使用中可以100条，然后清理list，方便内存回收
     */
    private static final int BATCH_COUNT = 100;

    /**
     * 缓存的数据
     */
    private List<BookImportDTO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data    one row value. Is same as {@link AnalysisContext#readRowHolder()}
     * @param context analysis context
     */
    @Override
    public void invoke(BookImportDTO data, AnalysisContext context) {
        log.info("解析到一条数据:{}", data);
        
        // 数据转换和验证
        convertAndValidateData(data);
        
        log.info("转换后数据: publishDate={}, price={}, totalCopies={}", 
                data.getPublishDate(), data.getPrice(), data.getTotalCopies());
        
        cachedDataList.add(data);
        
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context analysis context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成！");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据，开始存储数据库！", cachedDataList.size());
        // 这里可以调用service进行批量保存
        // bookService.batchSave(cachedDataList);
        log.info("存储数据库成功！");
    }

    /**
     * 数据转换和验证
     */
    private void convertAndValidateData(BookImportDTO data) {
        // 转换出版日期
        if (data.getPublishDateStr() != null && !data.getPublishDateStr().trim().isEmpty()) {
            try {
                String dateStr = data.getPublishDateStr().trim();
                LocalDate publishDate = null;
                
                // 尝试多种日期格式
                String[] patterns = {
                    "yyyy-MM-dd",     // 2023-03-20
                    "yyyy/M/d",       // 2023/3/20
                    "yyyy/MM/dd",     // 2023/03/20
                    "yyyy-M-d",       // 2023-3-20
                    "yyyy-MM-d",      // 2023-03-20
                    "yyyy-M-dd"       // 2023-3-20
                };
                
                for (String pattern : patterns) {
                    try {
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
                        publishDate = LocalDate.parse(dateStr, formatter);
                        break;
                    } catch (DateTimeParseException ignored) {
                        // 继续尝试下一个格式
                    }
                }
                
                if (publishDate != null) {
                    data.setPublishDate(publishDate);
                } else {
                    log.warn("日期格式错误，无法解析: {}", dateStr);
                }
            } catch (Exception e) {
                log.warn("日期转换异常: {}", data.getPublishDateStr(), e);
            }
        }

        // 转换价格
        if (data.getPriceStr() != null && !data.getPriceStr().trim().isEmpty()) {
            try {
                data.setPrice(new BigDecimal(data.getPriceStr().trim()));
            } catch (NumberFormatException e) {
                log.warn("价格格式错误: {}", data.getPriceStr());
                data.setPrice(BigDecimal.ZERO);
            }
        } else {
            data.setPrice(BigDecimal.ZERO);
        }

        // 转换总册数
        if (data.getTotalCopiesStr() != null && !data.getTotalCopiesStr().trim().isEmpty()) {
            try {
                data.setTotalCopies(Integer.parseInt(data.getTotalCopiesStr().trim()));
            } catch (NumberFormatException e) {
                log.warn("总册数格式错误: {}", data.getTotalCopiesStr());
                data.setTotalCopies(1);
            }
        } else {
            data.setTotalCopies(1);
        }

        // 数据验证
        validateRequiredFields(data);
    }

    /**
     * 验证必填字段
     */
    private void validateRequiredFields(BookImportDTO data) {
        if (data.getIsbn() == null || data.getIsbn().trim().isEmpty()) {
            throw new RuntimeException("ISBN号不能为空");
        }
        if (data.getBookName() == null || data.getBookName().trim().isEmpty()) {
            throw new RuntimeException("图书名称不能为空");
        }
        if (data.getAuthor() == null || data.getAuthor().trim().isEmpty()) {
            throw new RuntimeException("作者不能为空");
        }
        if (data.getCategoryName() == null || data.getCategoryName().trim().isEmpty()) {
            throw new RuntimeException("分类名称不能为空");
        }
    }

    /**
     * 获取解析的数据
     */
    public List<BookImportDTO> getCachedDataList() {
        return cachedDataList;
    }
}
